home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / etc / RCS / shm.c,v < prev    next >
Text File  |  1992-03-27  |  10KB  |  475 lines

  1. head     1.6;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.6
  10. date     92.03.27.12.25.31;  author shirriff;  state Exp;
  11. branches ;
  12. next     1.5;
  13.  
  14. 1.5
  15. date     90.06.27.11.17.58;  author shirriff;  state Exp;
  16. branches ;
  17. next     1.4;
  18.  
  19. 1.4
  20. date     90.05.21.17.00.51;  author shirriff;  state Exp;
  21. branches ;
  22. next     1.3;
  23.  
  24. 1.3
  25. date     90.03.19.13.32.36;  author jhh;  state Exp;
  26. branches ;
  27. next     1.2;
  28.  
  29. 1.2
  30. date     90.02.20.12.21.17;  author jhh;  state Exp;
  31. branches ;
  32. next     1.1;
  33.  
  34. 1.1
  35. date     90.02.20.12.14.35;  author jhh;  state Exp;
  36. branches ;
  37. next     ;
  38.  
  39.  
  40. desc
  41. @@
  42.  
  43.  
  44. 1.6
  45. log
  46. @Modified temp. shared file so different machines won't conflict.
  47. @
  48. text
  49. @/* 
  50.  * shm.c --
  51.  *
  52.  *    These routines map system V shared memory calls into 4.3 BSD
  53.  *    calls.
  54.  *
  55.  * Copyright 1990 Regents of the University of California
  56.  * Permission to use, copy, modify, and distribute this
  57.  * software and its documentation for any purpose and without
  58.  * fee is hereby granted, provided that the above copyright
  59.  * notice appear in all copies.  The University of California
  60.  * makes no representations about the suitability of this
  61.  * software for any purpose.  It is provided "as is" without
  62.  * express or implied warranty.
  63.  */
  64.  
  65. /*
  66. From dillon@@postgres.Berkeley.EDU Fri Jun 23 17:17:30 1989
  67.     Here is the support file I wrote for the postgres that implements
  68. most of the shared memory calls through mmap().  The line used to compile
  69. the module is:
  70.  
  71.     cc -I/usr/include -I/usr/att/usr/include -c port.c
  72.  
  73.     The module is not 100% transparent but works well enough that most
  74. programs which use the shared memory calls don't know the difference.
  75.  
  76.     From working with both the shared memory calls and the mmap() calls
  77. It is clear that the mmap() calls are not only superior, but integrate well
  78. into the system whereas the shared memory calls are really nothing more than
  79. a huge hack.  For example, on SUNs one must compile in the exact amount of
  80. memory to reserved for shared memory and this memory cannot be used by the
  81. VM.  What a waste!  The sequent's Dynix OS, on the otherhand, and the mmap()
  82. call in general has no such restrictions.
  83.  
  84.     I'm going blind into this.  Hopefully you have access to both the
  85. mmap includes and the AT&T shared memory includes.
  86.  
  87.                 Luck,
  88.  
  89.  
  90.                     -Matt
  91. */
  92.  
  93. #ifndef lint
  94. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/shm.c,v 1.5 90/06/27 11:17:58 shirriff Exp Locker: shirriff $ SPRITE (Berkeley)";
  95. #endif /* not lint */
  96. #include <stdio.h>
  97. #include <fcntl.h>
  98. #include <sys/types.h>
  99. #include <sys/stat.h>
  100. #include <sys/ipc.h>
  101. #include <sys/shm.h>    /* att-include file    */
  102. #include <sys/mman.h>
  103. #include <assert.h>
  104.  
  105. #ifndef __STDC__
  106. #define void char
  107. #endif
  108.  
  109. #define LEN 64
  110. #define PRIV "/tmp/post.phm.%d"
  111. #define SHARED "/tmp/post.shm.%d.%d"
  112.  
  113. extern int errno;
  114.  
  115. typedef struct {
  116.     void  *base;
  117.     long  size;
  118.     short exists;
  119.     int key;
  120.     char name[LEN];
  121. } SHMIDS;
  122.  
  123. int _shmTrace = 0;
  124.  
  125. /*
  126.  * In sprite there is no limit on the number of file descriptors.
  127.  * Set this to 64 because that is how many ultrix allows.
  128.  */
  129.  
  130. #ifndef _NFILE
  131. #define _NFILE 64
  132. #endif
  133.  
  134. static SHMIDS ShmIds[_NFILE];
  135.  
  136. /*
  137.  *  shmget(key, size, shmflg)
  138.  *
  139.  *  key might be IPC_PRIVATE in which case a 'private' segment is created
  140.  *  shmflg = file permissions
  141.  *  size = size of shared memory segment
  142.  */
  143.  
  144. shmget(key, size, shmflg)
  145. key_t key;
  146. int size, shmflg;
  147. {
  148.     int fd;
  149.     char buf[LEN];
  150.     int fileflags = O_RDWR;
  151.     extern int errno;
  152.     int i;
  153.  
  154.     if (_shmTrace) {
  155.     printf("call: shmget(%d, %d, %d)\n", key, size, shmflg);
  156.     }
  157.     if ((shmflg & IPC_CREAT) || (shmflg & IPC_PRIVATE))
  158.     fileflags |= O_CREAT;
  159.     if (shmflg & IPC_NOWAIT)
  160.     fileflags |= O_NDELAY;
  161.     if (shmflg & IPC_EXCL)
  162.     fileflags |= O_EXCL;
  163.     if (shmflg & IPC_ALLOC) {
  164.     fprintf(stderr, "shmget: IPC_ALLOC flag not implemented\n");
  165.     exit(1);
  166.     }
  167.  
  168.     if (key == IPC_PRIVATE)
  169.     sprintf(buf, PRIV, getpid());
  170.     else
  171.     sprintf(buf, SHARED, gethostid(), key);
  172.     fd = open(buf, fileflags, (shmflg & 0777) | 0600);
  173.     if (fd < 0) {
  174.     return -1;
  175.     }
  176.     if ((fileflags & O_CREAT) || key == IPC_PRIVATE) {
  177.     lseek(fd,(long)size-1,0);
  178.     read(fd,buf,1);
  179.     lseek(fd,(long)size-1,0);
  180.     write(fd,buf,1);
  181.     } else {
  182.     size = lseek(fd,0L,2);
  183.     lseek(fd,0L,0);    /* not really needed, in for conformity */
  184.     if (_shmTrace) {
  185.         printf("Segment already has length %d\n", size);
  186.     }
  187.     }
  188.     if (key == IPC_PRIVATE) {
  189.     unlink(buf);
  190.     } else {
  191.     /*
  192.      * See if we already have an entry in the table.
  193.      */
  194.     for (i=0; i< _NFILE; i++) {
  195.         if (key == ShmIds[i].key && ShmIds[i].exists) {
  196.         close(fd);
  197.         if (_shmTrace) {
  198.             printf("Segment already exists as %d\n", i);
  199.         }
  200.         return i;
  201.         }
  202.     }
  203.     }
  204.     ShmIds[fd].size = size;
  205.     ShmIds[fd].base = (void *)0L;
  206.     ShmIds[fd].exists = 1;
  207.     ShmIds[fd].key = key;
  208.     strncpy(ShmIds[fd].name, buf, LEN);
  209.     if (_shmTrace) {
  210.     printf("shmget returning %d\n", fd);
  211.     }
  212.     return(fd);
  213. }
  214.  
  215. shmop()
  216. {
  217.     assert(0);
  218. }
  219.  
  220. shmctl(shmid, cmd, buf)
  221. int shmid, cmd;
  222. struct shmid_ds *buf;    /* sys/shm.h att-includes */
  223. {
  224.     struct stat stat;
  225.     int result = 0;
  226.  
  227.     if (_shmTrace) {
  228.     printf("call: shmctl(%d, %d, %d)\n", shmid, cmd, buf);
  229.     }
  230.     assert(shmid >= 0 && shmid < _NFILE);
  231.     assert(ShmIds[shmid].exists);
  232.  
  233.     fstat(shmid, &stat);
  234.  
  235.     switch(cmd) {
  236.     case IPC_STAT:
  237.     buf->shm_perm.mode= stat.st_mode;
  238.     buf->shm_perm.uid = stat.st_uid;
  239.     buf->shm_perm.gid= stat.st_gid;
  240.     buf->shm_perm.cuid = stat.st_uid;
  241.     buf->shm_perm.cgid= stat.st_gid;
  242.     buf->shm_perm.key = shmid;
  243.     buf->shm_atime = stat.st_atime;
  244.     buf->shm_ctime = stat.st_ctime;
  245.     /* fill in more??? */
  246.     break;
  247.     case IPC_SET:    /* set only uid, guid, and low 9 bits of mode   */
  248.     fchmod(shmid, (stat.st_mode & ~0777) | (buf->shm_perm.mode & 0777));
  249.     fchown(shmid, buf->shm_perm.uid, buf->shm_perm.gid);
  250.     break;
  251.     case IPC_RMID:   /* delete the shared memory identifier        */
  252.     if (ShmIds[shmid].key != IPC_PRIVATE) {
  253.         unlink(ShmIds[shmid].name);
  254.     }
  255.     close(shmid);
  256.     ShmIds[shmid].exists = 0;
  257.     ShmIds[shmid].key = -1;
  258.     break;
  259.     }
  260.     return(result);
  261. }
  262.  
  263. char *
  264. shmat(shmid, shmaddr, shmflg)
  265. int shmid;
  266. int shmaddr;
  267. int shmflg;
  268. {
  269.     void *base;
  270.     long size;
  271.     long pgmask = getpagesize() - 1;
  272.  
  273.     if (_shmTrace) {
  274.     printf("call: shmat(%d, %d, %d)\n", shmid, shmaddr, shmflg);
  275.     }
  276.     assert(!shmaddr);
  277.     assert(!shmflg);
  278.  
  279.     assert(shmid >= 0 && shmid < _NFILE);
  280.     assert(ShmIds[shmid].exists);
  281.  
  282.     if (ShmIds[shmid].base)        /* already mapped! */
  283.     return((char *)ShmIds[shmid].base);
  284.     base = (void *)(((int)sbrk(0) + pgmask) & ~pgmask);
  285.     size = (ShmIds[shmid].size + pgmask) & ~pgmask;
  286.     if (_shmTrace) {
  287.     printf("Mapping: length = %d\n", size);
  288.     }
  289.     if (_shmTrace) {
  290.     printf("shmat: calling mmap(%x, %d, %d, %d, %d, %d)\n", base, size,
  291.         PROT_READ|PROT_WRITE, MAP_SHARED, shmid, 0);
  292.     }
  293.     base = (void *)mmap(base, size, PROT_READ|PROT_WRITE, MAP_SHARED,
  294.         shmid, 0);
  295.     if (base < 0) {
  296.     if (_shmTrace) {
  297.         printf("mmap failed: base = %d, errno = %d\n", base, errno);
  298.     }
  299.     return((char *)-1);
  300.     }
  301.     ShmIds[shmid].base = base;
  302.     if (_shmTrace) {
  303.     printf("shmat returning 0x%x\n", base);
  304.     }
  305.     return((char *)base);
  306. }
  307.  
  308. int
  309. shmdt(shmaddr)
  310. void *shmaddr;
  311. {
  312.     short i;
  313.  
  314.     if (_shmTrace) {
  315.     printf("call: shmdt(%d)\n", shmaddr);
  316.     }
  317.     assert(shmaddr);
  318.  
  319.     for (i = 0; i < _NFILE; ++i) {
  320.     if (ShmIds[i].exists && ShmIds[i].base == shmaddr) {
  321.         if (munmap(ShmIds[i].base, ShmIds[i].size) < 0) {
  322.         fprintf(stderr, "munmap failed!\n");
  323.         exit(1);
  324.         }
  325.         ShmIds[i].base = 0;
  326.         break;
  327.     }
  328.     }
  329.     return(0);
  330. }
  331.  
  332.  
  333.  
  334. @
  335.  
  336.  
  337. 1.5
  338. log
  339. @Fixed a bunch of bugs.  Added tracing.
  340. @
  341. text
  342. @d46 1
  343. a46 1
  344. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/shm.c,v 1.4 90/05/21 17:00:51 shirriff Exp Locker: shirriff $ SPRITE (Berkeley)";
  345. d62 2
  346. d121 1
  347. a121 1
  348.     sprintf(buf, "/tmp/post.phm.%d", getpid());
  349. d123 1
  350. a123 1
  351.     sprintf(buf, "/tmp/post.shm.%d", key);
  352. @
  353.  
  354.  
  355. 1.4
  356. log
  357. @Removed some debugging statements.  Fixed error return.
  358. @
  359. text
  360. @d46 1
  361. a46 1
  362. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/shm.c,v 1.2 90/02/20 12:21:17 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  363. d61 4
  364. d69 2
  365. d73 2
  366. d99 1
  367. a99 1
  368.     char buf[64];
  369. d102 1
  370. a102 1
  371.     void *base;
  372. d104 4
  373. a107 1
  374.     if (shmflg & IPC_CREAT)
  375. d123 9
  376. a131 1
  377.     if (!(fileflags & O_CREAT) && fd >= 0) {
  378. d134 19
  379. d154 7
  380. a160 7
  381.     if (fd >= 0) {
  382.     if (key == IPC_PRIVATE)
  383.         unlink(buf);
  384.     assert(fd < _NFILE);
  385.     ShmIds[fd].size = size;
  386.     ShmIds[fd].base = (void *)0L;
  387.     ShmIds[fd].exists = 1;
  388. d177 3
  389. d202 3
  390. d207 1
  391. a221 1
  392.     int result;
  393. d223 3
  394. d236 9
  395. a244 1
  396.     base = (void *)mmap(base, size, PROT_RDWR, MAP_SHARED, shmid, 0);
  397. d246 3
  398. a250 4
  399.     if (result < 0)
  400.     perror(result);
  401.     if (result < 0)
  402.     return((char *)-1);
  403. d252 3
  404. d264 3
  405. @
  406.  
  407.  
  408. 1.3
  409. log
  410. @changed Assert to assert
  411. @
  412. text
  413. @a114 1
  414.     printf("Autosize %d\n", size);
  415. a115 1
  416.     printf("%d = open(%s, 0%o, 0%o)\n", fd, buf, fileflags, (shmflg&0777)|0600);
  417. a123 1
  418.     printf("shared memory (fd %d size %d) %s\n", fd, size, buf);
  419. d189 2
  420. a190 1
  421.     if (mmap(base, size, PROT_RDWR, MAP_SHARED, shmid, 0) < 0) {
  422. a192 4
  423.     printf("mmap base = %08lx, size = %ld, prot = 0%o, shared = %d, fd = %d\n",
  424.     base, size, PROT_RDWR, MAP_SHARED, shmid
  425.     );
  426.     printf("result %d\n", result);
  427. @
  428.  
  429.  
  430. 1.2
  431. log
  432. @ported to sprite
  433. @
  434. text
  435. @d46 1
  436. a46 1
  437. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/proto.c,v 1.3 90/01/12 12:03:36 douglis Exp $ SPRITE (Berkeley)";
  438. d55 1
  439. d121 1
  440. a121 1
  441.     Assert(fd < _NFILE);
  442. d132 1
  443. a132 1
  444.     Assert(0);
  445. d142 2
  446. a143 2
  447.     Assert(shmid >= 0 && shmid < _NFILE);
  448.     Assert(ShmIds[shmid].exists);
  449. d182 2
  450. a183 2
  451.     Assert(!shmaddr);
  452.     Assert(!shmflg);
  453. d185 2
  454. a186 2
  455.     Assert(shmid >= 0 && shmid < _NFILE);
  456.     Assert(ShmIds[shmid].exists);
  457. d213 1
  458. a213 1
  459.     Assert(shmaddr);
  460. @
  461.  
  462.  
  463. 1.1
  464. log
  465. @Initial revision
  466. @
  467. text
  468. @d5 1
  469. a5 1
  470.  *    calls..
  471. d17 28
  472. d56 4
  473. d65 9
  474. @
  475.